﻿namespace TreeViewMVVMInPlaceEditingDemo.InPlaceEdit.ViewModel
{
  using System.Collections.ObjectModel;
  using System.ComponentModel;
  using System.Linq;
  using BusinessLib;

  /// <summary>
  /// A UI-friendly wrapper around a Person object.
  /// </summary>
  public class PersonViewModel : INotifyPropertyChanged
  {
    #region Data
    private readonly ReadOnlyCollection<PersonViewModel> _children;
    private readonly PersonViewModel _parent;
    private readonly Person _person;
    private bool _isExpanded;
    private bool _isSelected;
    #endregion // Data

    #region Constructors
    public PersonViewModel(Person person) : this(person, null)
    {
    }

    private PersonViewModel(Person person, PersonViewModel parent)
    {
      _person = person;
      _parent = parent;

      _children =
        new ReadOnlyCollection<PersonViewModel>(
          (_person.Children.Select(child => new PersonViewModel(child, this))).ToList());
    }
    #endregion // Constructors

    #region Person Properties
    public ReadOnlyCollection<PersonViewModel> Children
    {
      get { return _children; }
    }

    public string Name
    {
      get { return _person.Name; }
      set
      {
        if (_person.Name != value)
        {
          _person.Name = value;
          OnPropertyChanged("Name");
        }
      }
    }
    #endregion // Person Properties

    #region Presentation Members
    #region IsExpanded
    /// <summary>
    /// Gets/sets whether the TreeViewItem 
    /// associated with this object is expanded.
    /// </summary>
    public bool IsExpanded
    {
      get { return _isExpanded; }
      set
      {
        if (value != _isExpanded)
        {
          _isExpanded = value;
          OnPropertyChanged("IsExpanded");
        }

        // Expand all the way up to the root.
        if (_isExpanded && _parent != null)
          _parent.IsExpanded = true;
      }
    }
    #endregion // IsExpanded

    #region IsSelected
    /// <summary>
    /// Gets/sets whether the TreeViewItem 
    /// associated with this object is selected.
    /// </summary>
    public bool IsSelected
    {
      get { return _isSelected; }
      set
      {
        if (value != _isSelected)
        {
          _isSelected = value;
          OnPropertyChanged("IsSelected");
        }
      }
    }
    #endregion // IsSelected

    #region Parent
    public PersonViewModel Parent
    {
      get { return _parent; }
    }
    #endregion // Parent
    #endregion // Presentation Members

    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
      if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion // INotifyPropertyChanged Members
  }
}